<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 1、手写call
        Function.prototype.myCall = function (context, ...args) {
            // 如果没有传入 context，则默认为全局对象
            context = context || globalThis;
            // 在 context 上创建一个唯一的属性，用于存储函数引用
            const fnSymbol = Symbol();
            context[fnSymbol] = this;
            // 调用函数并传递参数
            const result = context[fnSymbol](...args);
            // 删除临时属性
            delete context[fnSymbol];
            // 返回函数调用的结果
            return result;
        };
        // 2、手写apply
        Function.prototype.myApply = function (context, args) {
            // 如果没有传入 context，则默认为全局对象
            context = context || globalThis;
            // 在 context 上创建一个唯一的属性，用于存储函数引用
            const fnSymbol = Symbol();
            context[fnSymbol] = this;
            // 调用函数并传递参数
            let result;
            if (args) {
                result = context[fnSymbol](...args);
            } else {
                result = context[fnSymbol]();
            }
            // 删除临时属性
            delete context[fnSymbol];
            // 返回函数调用的结果
            return result;
        };
        // 3、手写bind
        Function.prototype.myBind = function (context, ...args) {
            // 保存函数引用
            const fn = this;
            // 返回一个新的函数
            return function (...newArgs) {
                // 调用原函数，并指定 this 和参数
                return fn.apply(context, args.concat(newArgs));
            };
        };
        // 示例
        function foo(a,b,c) {
            console.log(this.name)
            console.log(a+b+c)
        }
        function foo2(a,b,c) {
            console.log(this.name)
            console.log(a+b+c)
        }
        const obj = {
            name: 'obj',
            // foo: foo,
            // foo2:foo2
        }
        foo.myCall(obj, 1,2,3)
        foo2.myApply(obj,[1,2,3])

        function greet(){
            console.log(`hello,${this.name}`)
        }
        const person = {name:'slice'}
        const greetPerson = greet.myBind(person)
        greetPerson()
        
    </script>
</body>

</html>